home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
gnu
/
gcc_260.zip
/
gcc_260
/
cp
/
lib-except.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-06
|
5KB
|
204 lines
/* terminate(), unexpected(), set_terminate(), set_unexpected()
as well as the default terminate func and default unexpected func
====================================================================== */
typedef void (*vfp)();
void
__default_terminate()
{
abort();
}
void
__default_unexpected()
{
__default_terminate();
}
static vfp __terminate_func = __default_terminate;
static vfp __unexpected_func = __default_unexpected;
vfp
set_terminate(func)
vfp func;
{
vfp old = __terminate_func;
__terminate_func = func;
return old;
}
vfp
set_unexpected(func)
vfp func;
{
vfp old = __unexpected_func;
__unexpected_func = func;
return old;
}
void
terminate()
{
__terminate_func();
}
void
unexpected()
{
__unexpected_func();
}
/* ====================================================================== */
typedef struct {
void *start;
void *end;
void *exception_handler;
} exception_table;
static int except_table_pos = 0;
static void *except_pc = (void *)0;
extern exception_table __EXCEPTION_TABLE__[];
/* this routine takes a pc, and the address of the exception handler associated
with the closest exception table handler entry associated with that PC,
or 0 if there are no table entries the PC fits in. The algorithm works
something like this:
while(current_entry exists) {
if(current_entry.start < pc )
current_entry = next_entry;
else {
if(prev_entry.start <= pc && prev_entry.end > pc) {
save pointer to prev_entry;
return prev_entry.exception_handler;
}
else return 0;
}
}
return 0;
Assuming a correctly sorted table (ascending order) this routine should
return the tighest match...
In the advent of a tie, we have to give the last entry, as it represents
an inner block.
*/
void *
__find_first_exception_table_match(pc)
void *pc;
{
extern int printf(...);
exception_table *table = __EXCEPTION_TABLE__;
int pos = 0;
int best = 0;
#if 0
printf("find_first_exception_table_match(): pc = %x!\n",pc);
#endif
except_pc = pc;
#if 0
/* We can't do this yet, as we don't know that the table is sorted. */
do {
++pos;
if (table[pos].start > except_pc)
/* found the first table[pos].start > except_pc, so the previous
entry better be the one we want! */
break;
} while(table[pos].exception_handler != (void*)-1);
--pos;
if (table[pos].start <= except_pc && table[pos].end > except_pc)
{
except_table_pos = pos;
#if 0
printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
#endif
return table[pos].exception_handler;
}
#else
while (table[++pos].exception_handler != (void*)-1) {
if (table[pos].start <= except_pc && table[pos].end > except_pc)
{
/* This can apply. Make sure it is better or as good as the previous
best. */
/* The best one ends first. */
if (best == 0 || (table[pos].end <= table[best].end
/* The best one starts last. */
&& table[pos].start >= table[best].start))
best = pos;
}
}
if (best != 0)
return table[best].exception_handler;
#endif
#if 0
printf("find_first_eh_table_match(): else: returning NULL!\n");
#endif
return (void*)0;
}
#if 0
/* this routine returns the next tighest exception table match for the
current except_pc, or 0 if there aren't any wider entries (meaning
we need to either unwind a level and call
find_first_exception_table_match() with the new pc, or we need to
call terminate() because there are no more layers to unwind. */
void *
__find_next_exception_table_match()
{
exception_table *table = __EXCEPTION_TABLE__;
int pos = except_table_pos;
extern int printf(...);
printf("__find_next_exception_table_match(): table = %x, pos = %d, except_pc = %x\n",table,pos,except_pc);
if(! --pos) {
except_table_pos = 1;
return (void*)0;
}
if(table[pos].start <= except_pc && table[pos].end >= except_pc) {
except_table_pos = pos;
printf("__find_next_exception_table_match(): found match: %x\n",table[pos].exception_handler);
return table[pos].exception_handler;
}
else {
except_table_pos = 1;
return (void*)0;
}
}
#endif
#if 0
void
__unwind_function(void *frameaddr)
{
extern int printf(...);
printf("__unwind_function(): frameaddr = %x\n",frameaddr);
}
#endif
int
__throw_type_match (const char *catch_type, const char *throw_type)
{
extern int printf(...);
#if 0
printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
catch_type, throw_type);
#endif
return strcmp (catch_type, throw_type);
}